"""
Broadcast routing implementation
"""
from typing import Callable, Dict, List, Optional, Set
from ...core.message import Message

class BroadcastPattern:
    """广播模式类"""
    
    def __init__(self, targets: List[str], condition: Optional[Callable[[Message], bool]] = None, 
                 description: str = ""):
        """
        初始化广播模式
        Args:
            targets: 广播目标代理ID列表
            condition: 可选的广播条件，None表示无条件广播
            description: 广播规则描述
        """
        self.targets = targets
        self.condition = condition
        self.description = description or "Default broadcast"
        
    def should_broadcast(self, message: Message) -> bool:
        """
        检查是否应该广播消息
        Args:
            message: 待检查的消息
        Returns:
            是否应该广播
        """
        if self.condition is None:
            return True
            
        try:
            return self.condition(message)
        except Exception as e:
            print(f"Error evaluating broadcast condition: {str(e)}")
            return False
            
    def get_targets(self) -> List[str] | None:
        """获取广播目标列表"""
        return self.targets

class BroadcastRouter:
    """广播路由器"""
    
    def __init__(self):
        # {source_agent: [BroadcastPattern]}
        self.patterns: Dict[str, List[BroadcastPattern]] = {}
        
    def add_broadcast_pattern(self, source: str, targets: List[str] = None,
                            condition: Optional[Callable[[Message], bool]] = None,
                            description: str = "") -> None:
        """
        添加广播模式
        Args:
            source: 源代理ID
            targets: 广播目标列表
            condition: 可选的广播条件
            description: 广播规则描述
        """
        if source not in self.patterns:
            self.patterns[source] = []
            
        pattern = BroadcastPattern(targets, condition, description)
        self.patterns[source].append(pattern)
        
    def get_broadcast_targets(self, message: Message) -> List[str]:
        """
        获取消息的广播目标列表
        Args:
            message: 消息对象
        Returns:
            应该接收广播的代理ID列表
        """
        if message.sender not in self.patterns:
            return []
            
        targets = set()
        for pattern in self.patterns[message.sender]:
            if pattern.should_broadcast(message):
                targets.update(pattern.get_targets())
                
        # 移除发送者自己
        targets.discard(message.sender)
        # 移除消息的直接接收者（如果有）
        if message.receiver:
            targets.discard(message.receiver)
            
        return list(targets)
        
    def get_patterns_for_agent(self, agent_id: str) -> List[Dict]:
        """
        获取代理的所有广播模式信息
        Args:
            agent_id: 代理ID
        Returns:
            广播模式信息列表
        """
        if agent_id not in self.patterns:
            return []
            
        patterns_info = []
        for pattern in self.patterns[agent_id]:
            patterns_info.append({
                "targets": pattern.get_targets(),
                "description": pattern.description,
                "has_condition": pattern.condition is not None
            })
        return patterns_info
        
    def clear_patterns(self, agent_id: Optional[str] = None) -> None:
        """
        清除广播模式
        Args:
            agent_id: 要清除的代理ID，None表示清除所有模式
        """
        if agent_id is None:
            self.patterns.clear()
        elif agent_id in self.patterns:
            self.patterns[agent_id].clear()
            
    def get_all_targets(self) -> Set[str]:
        """
        获取所有可能的广播目标
        Returns:
            目标代理ID集合
        """
        targets = set()
        for patterns in self.patterns.values():
            for pattern in patterns:
                targets.update(pattern.get_targets())
        return targets

class CommonBroadcastConditions:
    """预定义的常用广播条件"""
    
    @staticmethod
    def message_type_is(msg_type: str) -> Callable[[Message], bool]:
        """
        创建基于消息类型的广播条件
        Args:
            msg_type: 消息类型名称
        Returns:
            条件函数
        """
        def condition(message: Message) -> bool:
            return message.type.name == msg_type
        return condition
        
    @staticmethod
    def content_matches(keyword: str) -> Callable[[Message], bool]:
        """
        创建基于内容关键词的广播条件
        Args:
            keyword: 关键词
        Returns:
            条件函数
        """
        def condition(message: Message) -> bool:
            return keyword.lower() in str(message.content).lower()
        return condition
        
    @staticmethod
    def has_metadata_tag(tag: str) -> Callable[[Message], bool]:
        """
        创建基于元数据标签的广播条件
        Args:
            tag: 标签名
        Returns:
            条件函数
        """
        def condition(message: Message) -> bool:
            if not message.metadata or "tags" not in message.metadata:
                return False
            tags = message.metadata["tags"]
            return tag in tags if isinstance(tags, (list, set)) else False
        return condition

    @staticmethod
    def has_metadata_key_value(key: str, value: str) -> Callable[[Message], bool]:
        """
        创建基于元数据键值对的广播条件
        Args:
            key: 键名
            value: 键值
        Returns:
            条件函数
        """
        def condition(message: Message) -> bool:
            if not message.metadata:
                return False
            return message.metadata.get(key) == value
        return condition